/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.service.impl;


import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.koron.audit.approval.AfterApprovalService;
import com.koron.audit.domain.Audit;
import com.koron.audit.management.FlowManagement;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.scene.domain.JSACorporation;
import com.koron.scene.domain.JSACorporationStep;
import com.koron.scene.mapper.JSACorporationMapper;
import com.koron.scene.mapper.JSACorporationStepMapper;
import com.koron.scene.service.api.JSACorporationService;
import com.koron.scene.utils.BusinessCode;
import com.koron.system.domain.DictData;
import com.koron.system.service.api.DictDataService;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class JSACorporationServiceImpl implements JSACorporationService, AfterApprovalService, InitializingBean {

    private final static  Logger logger = LoggerFactory.getLogger(JSACorporationServiceImpl.class);

    @Autowired
    private DictDataService dataService;

    // 状态:0-草稿 1-审批中 2-审批通过
    private String STATUS_0 = "0";
    private String STATUS_1 = "1";
    private String STATUS_2 = "2";

    @Value("${jsa_template_creation}")
    private String templateKey;
    
    @Value("${flow.scene.setCode}")
    private String setCode;

    @Autowired
    private FlowManagement flowManagement;

    @Override
    public List<JSACorporation> queryJSAByCondition(String corpCode, String name, String jsaTypeId) {
        if (logger.isDebugEnabled()) {
            logger.debug("name = {}, jsaTypeId = {}", name, jsaTypeId);
        }
        try (SessionFactory factory = new SessionFactory()) {
            JSACorporationMapper mapper = factory.getMapper(JSACorporationMapper.class);
            return mapper.queryJSAByCondition(corpCode, name, jsaTypeId);
        }
    }

    @Override
    public DataBean<JSACorporation> fetchInstances(String corpCode, String name, String jsaTypeId, Integer start, Integer rows) {
        if (logger.isDebugEnabled()) {
            logger.debug("name = {}, jsaTypeId = {}", name, jsaTypeId);
        }
        try (SessionFactory factory = new SessionFactory()) {
            JSACorporationMapper mapper = factory.getMapper(JSACorporationMapper.class);
            List<JSACorporation> instances = mapper.queryByCondition(corpCode, name, jsaTypeId, start, rows);
            Integer total = mapper.countByCondition(corpCode, name, jsaTypeId);
            if (!instances.isEmpty()) {
                instances.forEach(instance -> setName(instance));
            }
            DataBean<JSACorporation> dataBean = new DataBean<>();
            dataBean.setList(instances);
            dataBean.setPageSize(rows);
            dataBean.setTotalNumber(total);
            if (rows != null) {
                dataBean.setTotalPage(total > rows ? (total % rows == 0 ? total / rows : total / rows + 1) : 1);
                dataBean.setPageNo(start / rows + 1);
            }

            return dataBean;
        }
    }


    @Override
    public JSACorporation fetchOne(String id) {
        if (logger.isDebugEnabled()) {
            logger.debug("id = {}", id);
        }
        try (SessionFactory factory = new SessionFactory()) {
            JSACorporation instance = factory.getMapper(JSACorporationMapper.class).queryOne(id);
            if (instance != null) {
                setName(instance);
                instance.setSteps(factory.getMapper(JSACorporationStepMapper.class).querySteps(id));
            }
            return instance;
        }
    }

    private void setName(JSACorporation instance) {
        Map<String, DictData> cacheMap = dataService.getCacheMap();
        if (StringUtils.isNotBlank(instance.getJsaTypeId())) {
            DictData dictData = cacheMap.get(instance.getJsaTypeId());
            instance.setJsaTypeName(dictData != null? dictData.getDictLabel() : "");
        }
    }

    @Override
    public MessageBean batchDetele(List<String> idList) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), "删除成功", void.class);
        if (idList == null || idList.isEmpty()) {
            return msg;
        }
        SessionFactory factory = null;
        try {
            factory = new SessionFactory();
            JSACorporation jsaCorporation;
            JSACorporationMapper jsaCorporationMapper = factory.getMapper(JSACorporationMapper.class);
            List<String> list;
            for (String id : idList) {
                jsaCorporation = jsaCorporationMapper.queryOne(id);
                if (jsaCorporation == null){
                    return msg;
                }else if (!STATUS_0.equals(jsaCorporation.getStatus())) {
                    factory.close(false);
                    msg.setCode(BusinessCode.EXCEPTION.getCode());
                    msg.setDescription("只能删除草稿状态的JSA台账");
                    return msg;
                }
                list = new ArrayList<>();
                list.add(id);
                // 删除 JSA台账
                jsaCorporationMapper.batchDetele(list);
                // 删除 JSA台账 细项信息
                factory.getMapper(JSACorporationStepMapper.class).deleteSteps(id);
            }
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (factory != null) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
        }finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }



    @Override
    public MessageBean persist(StaffBean user, JSACorporation instance, String managerCode) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        if (instance == null) {
            return msg;
        }
        if (user == null) {
            msg.setCode(BusinessCode.NO_LOGIN.getCode());
            msg.setDescription(BusinessCode.NO_LOGIN.getDescription());
            return msg;
        }
        instance.setAddUser(user.getCode());
        instance.setAddUserName(user.getName());
        instance.setAddTime(new Date());
        instance.setUpdateTime(instance.getAddTime());
        instance.setUpdateUser(user.getCode());
        instance.setUpdateUserName(user.getName());
        SessionFactory factory = new SessionFactory();
        try {
            Integer start = null, rows = null;
            String jsaTypeId = null;
            JSACorporation dest = null;
            JSACorporationMapper mapper = factory.getMapper(JSACorporationMapper.class);
            List<JSACorporation> jsaInstances = mapper.queryByCondition(instance.getCorpCode(), instance.getName(), jsaTypeId, start, rows);
            if (jsaInstances != null && !jsaInstances.isEmpty()) {
                jsaInstances = jsaInstances.stream().filter(one -> one.getName().equals(instance.getName())).collect(Collectors.toList());
                dest = !jsaInstances.isEmpty() ? jsaInstances.get(0) : null;
            }

            if (StringUtils.isBlank(instance.getId())) {
                if (dest != null) {
                    factory.close(false);
                    msg.setCode(BusinessCode.JSAINSTANCE_NAME_DUP.getCode());
                    msg.setDescription(BusinessCode.JSAINSTANCE_NAME_DUP.getDescription());
                    return msg;
                }
                instance.setId(DefaultIdGenerator.getInstance().generateLongId());
                if (!STATUS_1.equals(instance.getStatus())){
                    instance.setStatus(STATUS_0);
                }
                if (mapper.insert(instance) > 0 && persistSteps(factory, instance.getSteps(), instance.getId())) {
                    // 如果申请状态(0-草稿 1-审批中 2-审批通过) 为审批中，则启动流程
                    if (STATUS_1.equals(instance.getStatus())) {
                        if (StringUtils.isEmpty(managerCode)) {
                            factory.close(false);
                            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                            msg.setDescription("请选择审核人");
                            return msg;
                        }
                        Audit audit = new Audit("JSA台账", "JSA台账审批", user.getName(), new Date());
                        audit.setTitle("JSA台账");
                        audit.setDescription("JSA台账审批");
                        audit.setCorpCode(instance.getCorpCode());
                        audit.setCorpName(instance.getCorpName());

                        audit.setId(DefaultIdGenerator.getInstance().generateLongId());
                        audit.setInitiatorCode(user.getCode());
                        audit.setTarget(this.getClass().getName());
                        audit.setTemplateKey(templateKey);
                        audit.setSetCode(setCode);
                        audit.setOperation(1);
                        audit.setState(1);
                        audit.setFlowType(1);
                        audit.setFlowName("新增JSA台账");
                        List<String> idList = Arrays.asList(instance.getId());
                        audit.setBusinessIds(new Gson().toJson(idList));
                        Map map = new HashMap();
                        map.put("personCode", managerCode);
                        if (!flowManagement.initFlow(user, audit, map)) {
                            factory.close(false);
                            msg.setCode(com.koron.hazardsource.util.BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                            msg.setDescription(com.koron.hazardsource.util.BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
                            return msg;
                        }
                    }
                    factory.close(true);
                    return msg;
                }else {
                    factory.close(false);
                    msg.setCode(BusinessCode.EXCEPTION.getCode());
                    msg.setDescription(BusinessCode.EXCEPTION.getDescription());
                    return msg;
                }
            } else {
                if (dest != null && !dest.getId().equals(instance.getId())) {
                    factory.close(false);
                    msg.setCode(BusinessCode.JSAINSTANCE_NAME_DUP.getCode());
                    msg.setDescription(BusinessCode.JSAINSTANCE_NAME_DUP.getDescription());
                    return msg;
                }
                JSACorporation jsaCorporation = mapper.queryOne(instance.getId());
                if (jsaCorporation == null){
                    factory.close(false);
                    msg.setCode(BusinessCode.EXCEPTION.getCode());
                    msg.setDescription("该JSA台账已失效");
                    return msg;
                }else if (!STATUS_0.equals(jsaCorporation.getStatus())) {
                    factory.close(false);
                    msg.setCode(BusinessCode.EXCEPTION.getCode());
                    msg.setDescription("只能修改草稿状态的JSA台账");
                    return msg;
                }
                if (mapper.update(instance) > 0 && persistSteps(factory, instance.getSteps(), instance.getId())) {
                    // 如果申请状态(0-草稿 1-审批中 2-审批通过) 为审批中，则启动流程
                    if (STATUS_1.equals(instance.getStatus())) {
                        if (StringUtils.isEmpty(managerCode)) {
                            factory.close(false);
                            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
                            msg.setDescription("请选择审核人");
                            return msg;
                        }
                        Audit audit = new Audit("JSA台账", "JSA台账审批", user.getName(), new Date());
                        audit.setTitle("JSA台账");
                        audit.setDescription("JSA台账审批");
                        audit.setCorpCode(instance.getCorpCode());
                        audit.setCorpName(instance.getCorpName());

                        audit.setId(DefaultIdGenerator.getInstance().generateLongId());
                        audit.setInitiatorCode(user.getCode());
                        audit.setTarget(this.getClass().getName());
                        audit.setSetCode(setCode);
                        audit.setTemplateKey(templateKey);
                        audit.setOperation(1);
                        audit.setState(1);
                        audit.setFlowType(1);
                        audit.setFlowName("新增JSA台账");
                        List<String> idList = Arrays.asList(instance.getId());
                        audit.setBusinessIds(new Gson().toJson(idList));
//                        Map map = new HashMap();
//                        map.put("personCode", managerCode);
                        if (!flowManagement.initFlow(user, audit, new HashMap())) {
                            factory.close(false);
                            msg.setCode(com.koron.hazardsource.util.BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                            msg.setDescription(com.koron.hazardsource.util.BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
                            return msg;
                        }
                    }
                    factory.close(true);
                    return msg;
                }else {
                    factory.close(false);
                    msg.setCode(BusinessCode.EXCEPTION.getCode());
                    msg.setDescription(BusinessCode.EXCEPTION.getDescription());
                    return msg;
                }
            }
        } catch (Exception e) {
            factory.close(false);
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }


    private boolean persistSteps(SessionFactory factory, List<JSACorporationStep> steps, String jsaId) {
        try {
            if (steps == null || steps.isEmpty()) {
                return true;
            }
            steps.stream().forEach(s -> s.setJsaId(jsaId));
            JSACorporationStepMapper mapper = factory.getMapper(JSACorporationStepMapper.class);
            List<JSACorporationStep> ulist = steps.stream().filter(instanceStep -> StringUtils.isNotBlank(instanceStep.getId())).collect(Collectors.toList());
            List<JSACorporationStep> ilist = steps.stream().filter(instanceStep -> StringUtils.isBlank(instanceStep.getId())).collect(Collectors.toList());
            List<JSACorporationStep> formers = mapper.querySteps(jsaId);
            formers.removeAll(ulist);
            if (!ulist.isEmpty()) {
                mapper.batchUpdate(ulist);
            }
            if (!ilist.isEmpty()) {
                for (JSACorporationStep jsaCorporationStep : ilist) {
                    jsaCorporationStep.setId(DefaultIdGenerator.getInstance().generateLongId());
                }
                mapper.batchInsert(ilist);
            }
            if (!formers.isEmpty()) {
                mapper.batchDetele(formers.stream().map(JSACorporationStep::getId).collect(Collectors.toList()));
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            return false;
        }
    }


    @Override
    public void editApproval(Audit audit) {
        Optional.ofNullable(audit)
                .map(obj -> obj.getBusinessIds())
                .map(ids -> {
                    List<String> list = JSON.parseArray(ids, String.class);
                    return Optional.ofNullable(list);
                }).map(idsList -> {
            List<String> idList = idsList.get();
            Optional.ofNullable(idList).map(ids -> {
                SessionFactory factory = new SessionFactory();
                try {
                    JSACorporationMapper mapper = factory.getMapper(JSACorporationMapper.class);
                    for (String id : ids) {
                        // 申请状态(0-草稿 1-审批中 2-已审批)
                        if (mapper.updateStatus(id, STATUS_2) != 1) {
                            factory.close(false);
                            return null;
                        }
                    }
                    factory.close();
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                    factory.close(false);
                }
                return null;
            });
            return null;
        });
    }

    @Override
    public void discardApproval(Audit audit) {

    }

    @Override
    public void processDiscard(Audit audit) {
        Optional.ofNullable(audit)
                .map(obj -> obj.getBusinessIds())
                .map(ids -> {
                    List<String> list = JSON.parseArray(ids, String.class);
                    return Optional.ofNullable(list);
                }).map(idsList -> {
            List<String> idList = idsList.get();
            Optional.ofNullable(idList).map(ids -> {
                SessionFactory factory = new SessionFactory();
                try {
                    JSACorporationMapper mapper = factory.getMapper(JSACorporationMapper.class);
                    for (String id : ids) {
                        // 申请状态(0-草稿 1-审批中 2-已审批)
                        if (mapper.updateStatus(id, STATUS_0) != 1) {
                            factory.close(false);
                            return null;
                        }
                    }
                    factory.close();
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                    factory.close(false);
                }
                return null;
            });
            return null;
        });
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        flowManagement.getHandlers().put(this.getClass().getName(), new JSACorporationServiceImpl());
    }

    @Override
    public void reject(Audit audit, List<String> userIdList) {
        // TODO 流程驳回操作
    }

    @Override
    public void passApproval(Integer operation, Audit audit) {
        // TODO 流程提交成功操作
    }
}
